package com.offcn.filter;

import com.offcn.utils.JwtUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {

    //令牌头名字
    private static final String AUTHORIZE_TOKEN = "Authorization";
    //用户登录地址
    private static final String USER_LOGIN_URL = "http://localhost:9100/oauth/login";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("全局拦截器");
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        //获取请求的URI
        String path = request.getURI().getPath();
        //如果是登录、goods等开放的微服务[这里的goods部分开放],则直接放行
        if (path.startsWith("/api/user/login") || path.startsWith("/api/brand/search/")) {
            //放行
            Mono<Void> filter = chain.filter(exchange);
            return filter; // 放行
        }

        //用户如果是登录或者一些不需要做权限认证的请求，直接放行
        String uri = request.getURI().toString();
        System.out.println("uri:" + uri);
        if(URLFilter.hasAuthorize(uri)){
            return chain.filter(exchange);
        }

        // 获取用户令牌信息
        //1.头文件
        String token = request.getHeaders().getFirst(AUTHORIZE_TOKEN);
        //判断令牌是否在头文件中
        boolean hasToken = true;
        // 2.参数中获取令牌
        if (StringUtils.isEmpty(token)) {
            token = request.getQueryParams().getFirst(AUTHORIZE_TOKEN);
            hasToken = false;
        }
        // 3.Cookie中获取
        if (StringUtils.isEmpty(token)) {
            hasToken = false;
            HttpCookie cookie = request.getCookies().getFirst(AUTHORIZE_TOKEN);
            if (cookie != null) {
                token = cookie.getValue();
            }
        }
        // 如果没有令牌，则拦截
        if (StringUtils.isEmpty(token)) {
//            response.setStatusCode(HttpStatus.UNAUTHORIZED);
//            return response.setComplete();
            return needAuthorization(USER_LOGIN_URL, exchange, uri);
        }
        // 如果有令牌，则校验令牌是否有效
        try { // 有效则放行
            JwtUtil.parseJWT(token);
            if (!hasToken) {
                request.mutate().header(HttpHeaders.AUTHORIZATION, "Bearer " + token);
            }
            return chain.filter(exchange);
        } catch (Exception e) {
            // 无效则拦截
            e.printStackTrace();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
    }

    @Override
    public int getOrder() {
        return 0;
    }

    /***
     * 响应设置
     * @param url
     * @param exchange
     * @return */
    public Mono<Void> needAuthorization(String url, ServerWebExchange exchange, String from) {
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.SEE_OTHER);
        response.getHeaders().set("Location", url + "?from=" + from);
        return exchange.getResponse().setComplete();
    }
}